/*
 * @Date: 2019-06-01 13:20:29
 * @Author: Ryan Huang
 * @Description:
 */
package main

import (
	"encoding/json"
	"fmt"
	"my/homework/chatroom1/constants"
	"my/homework/chatroom1/libs"
	"my/homework/chatroom1/libs/db"
	"my/homework/chatroom1/variables"
	"net"
	"strconv"
	"time"
)

var connections = make(map[net.Conn]string)
var nameConnections = make(map[string]net.Conn)

func main() {
	//tcpAddr := fmt.Sprintf(":%s", constants.Port)
	listen, _ := net.Listen(constants.TCP, constants.ServerAddr)
	defer listen.Close()
	for {
		conn, connErr := listen.Accept()
		connections[conn] = ""
		defer conn.Close()
		if connErr != nil {
			delete(connections, conn)
			continue
		}
		go receive(&conn)
	}
}

func receive(conn *net.Conn) {
	var ar = db.ResolveDB("", "")
	var affectedRows int
	var chatId int
	var userId int
	for {
		buf := make([]byte, constants.MessageMaxLen)
		n, err := (*conn).Read(buf)
		if err != nil {
			break
		}
		var msg map[string]interface{}
		json.Unmarshal(buf[:n], &msg)
		index := libs.GetValue(msg["index"])
		if index == float64(0) {
			//登录并且记录登录历史
			name := msg["name"].(string)
			password := msg["password"].(string)
			values := []string{name, libs.Md5(password)}
			result := ar.SetTable("users").SelectRaw("id").Where("name=? and password=? and is_del=0").First(values)
			userId, _ = strconv.Atoi(result["id"])
			var loginMsg string
			var ifLogin = false
			if len(result) == 0 {
				loginMsg = constants.WrongUserPass
			} else {
				connections[*conn] = name
				if ok := nameConnections[name]; ok != nil {
					loginMsg = constants.AccountLogined
				} else {
					nameConnections[name] = *conn
					loginMsg = constants.LoginSuccess
					ifLogin = true
					loginTime := strconv.FormatFloat(msg["time"].(float64), 'f', 0, 32)
					remoteAddr := libs.GetValue(msg["addr"])
					var inserts []map[string]string
					inserts = append(inserts, map[string]string{"user_id": result["id"], "remote_addr": remoteAddr.(string), "login_time": loginTime})
					affectedRows, chatId = ar.SetTable("login_history").Insert(inserts)
					if affectedRows == 0 {
						panic("history doesn't work")
					}
				}
			}
			var response = variables.Response{ifLogin, loginMsg, nil}
			(*conn).Write(libs.ToJson(response))
		} else {
			//开始聊
			//id chat_id user_id content create_time
			content := msg["body"].(string)
			inputTime := strconv.FormatFloat(msg["time"].(float64), 'f', 0, 32)
			createTime := time.Now().Unix()
			var chatContents []map[string]string
			chatContents = append(chatContents, map[string]string{
				"chat_id":     strconv.Itoa(chatId),
				"user_id":     strconv.Itoa(userId),
				"content":     content,
				"input_time":  inputTime,
				"create_time": strconv.Itoa(int(createTime)),
			})
			ar.SetTable("chat_history").Insert(chatContents)
			for singleConn, name := range connections {
				if singleConn == (*conn) {
					continue
				}
				feedbackMsg := fmt.Sprintf("%s : %s", name, content)
				var response = variables.Response{true, feedbackMsg, nil}
				singleConn.Write(libs.ToJson(response))
			}
		}
	}
}
